﻿using KAs.Application.Contract.Dto;
using KAs.Application.Contract.Svc;
using KAs.SqlSugar;
using Microsoft.Extensions;
using Microsoft.Extensions.Caching.Distributed;
using System.Text.RegularExpressions;
using Test.Application.Contract.Dto;
using Test.Application.Contract.Svc;
using Test.Domain;
using Test.Domain.Share;

namespace Test.Application;

// 无curd服务示例
public class UserAppService : IUserAppService
{
    private readonly IDistributedCache _cache;
    private readonly IRepository<UserInfo, long> _repository;
    private readonly ICurrentUserInfo _userInfo;

    public UserAppService(IDistributedCache cache, IRepository<UserInfo, long> repository, ICurrentUserInfo userInfo)
    {
        _cache = cache;
        _repository = repository;
        _userInfo = userInfo;
    }

    public async Task<LoginReturnDto> LoginAsync(LoginDto dto)
    {
        var userInfo = await _repository.GetFirstAsync(x => x.Account == dto.Account);
        if (userInfo == null || userInfo.Password != $"{dto.Password}pwd{dto.Account}".Md5Encryption())
            throw new Exception("账户名不存在或密码错误");
        var token = Guid.NewGuid().ToString("N");
        var userInfoDto = new UserInfoDto()
        {
            Uid = userInfo.Id.ToString(),
            Name = userInfo.UserName
        };
        await _cache.CacheAsync($"token:{token}", userInfoDto, 3600);
        var result = new LoginReturnDto()
        {
            Token = token,
            User = userInfo.SimpleMapTo<UserDto>()
        };
        return result;
    }

    public async Task<UserDto> RegisterAsync(RegisterDto dto)
    {
        var reg = new Regex(@"^[A-Za-z0-9]+$");
        if (!reg.IsMatch(dto.Account))
            throw new Exception("账户名必须由字母或数字构成");

        if (await _repository.IsAnyAsync(x => x.Account == dto.Account))
            throw new Exception("账户名已存在");

        dto.Gender ??= (int)GenderEnum.Secrecy;
        dto.Password = $"{dto.Password}pwd{dto.Account}".Md5Encryption();

        var entity = await _repository.InsertReturnEntityAsync(dto.SimpleMapTo<UserInfo>());
        return entity.SimpleMapTo<UserDto>();
    }

    public async Task<UserInfoDto> GetUserInfoAsync()
    {
        return _userInfo.GetUserInfo();
    }
}
